#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#include "zlink/ZLink.h"
#include "zlink/zlink_callback.h"


static pthread_t listen_thread;

static struct zlink_handle zlink_list[MAX_ZLINK_NUM];

static struct message_queue *usable_queue;
static struct message_queue *listened_queue;


void *zlink_listen_thread(void *data)
{
	int SID = 0;
	int ret = 0;
	struct message *msg = NULL;
	ZLink_SessionInfo sInfo;
	struct zlink_handle *handle = NULL;

	while(1) {
		msg = message_queue_receive(usable_queue);
		if (!msg)
			continue;
		if (!msg->data)
			break;

		SID = ZLink_Host_Listen(0);
		if (SID < 0) {
			fprintf(stderr, "Listen Error: %d \n", SID);
			message_queue_send(usable_queue, msg);
			continue;
		}

		memset(&sInfo, 0, sizeof(ZLink_SessionInfo));

		ret = ZLink_Session_GetInfo(SID, &sInfo);
		if (ret < 0) {
			fprintf(stderr, "ZLink_Session_GetInfo error: %d \n", ret);
			ZLink_Session_Close(SID);
			message_queue_send(usable_queue, msg);
			continue;
		}

		printf("zlink_info->name = %s, ip = %s\n", sInfo.name, sInfo.IP);

		handle = (void *)msg->data;
		handle->sid = SID;
		handle->sInfo = sInfo;

		message_queue_send(listened_queue, msg);
	}

    return NULL;
}

int init_zlink_media(void)
{
	int ret = 0;
	static int zlink_is_init = 0;

	if (zlink_is_init)
		return 0;

	ret = ZLink_Init(ZLINK_HOST, 10000, (char *)WLAN_NAME);
	if (ret != 0) {
		fprintf(stderr, "ZLink Init Error (%d)\n", ret);
		return -1;
	}

	ret = ZLink_Host_Init(ZLINK_USER_NAME, ZLINK_USER_PASS);
	if (ret != 0) {
		fprintf(stderr, "ZLink Init Error (%d)\n", ret);
		return -1;
	}

	zlink_is_init = 1;

    usable_queue = message_queue_create(0, 0);
    if (!usable_queue)
        return -1;

    listened_queue = message_queue_create(0,0);
    if (!listened_queue)
        return -1;

    int i = 0;
    for (i = 0;i < MAX_ZLINK_NUM; i++) {
        zlink_list[i].msg.data = (unsigned long)&zlink_list[i];
        message_queue_send(usable_queue, &zlink_list[i].msg);
    }

    pthread_create(&listen_thread, NULL, &zlink_listen_thread, NULL);

    return 0;
}

/*void *open_zlink_handle(char *data)*/
struct zlink_handle *open_zlink_handle(char *data)
{
	int ret;
	struct message *msg = NULL;
	struct zlink_handle *handle = NULL;

	init_zlink_media();

	msg = message_queue_receive_timeout(listened_queue, 500);
	if (!msg)
		return NULL;

	handle = (void *)msg;

	/* 若data不为mac地址，跳过以下操作 */
	if (data != NULL && *data != 0) {
		/* 若拿到的不是对应的 mac 地址，放回去listen_queue, 并延时100ms之后再重新获取 */
		if (strcmp(handle->sInfo.name, data) != 0) {
			message_queue_send(listened_queue, msg);
			usleep(100 * 1000);
			return NULL;
		}
	}

    handle->avid = ZLink_AV_Host_Start(handle->sid, 5000, 1, ZLINK_AV_CHANNEL);
    if (handle->avid < 0) {
        ZLink_Session_Close(handle->sid);
        message_queue_send(usable_queue, msg);
        return NULL;
    }

/*    return (void *)handle;*/
	return handle;
}



void wait_packet_timeout(struct zlink_handle *handle, int wait_cnt, int timeout_ms)
{
	int packet_cnt = 0;

	if (!handle)
		return;

	packet_cnt = ZLink_AV_Check_RecvVideoBuf(handle->avid);
	while (packet_cnt < wait_cnt) {
		usleep(1000);
		timeout_ms -= 1;

		if (timeout_ms == 0)
			break;

		packet_cnt = ZLink_AV_Check_RecvVideoBuf(handle->avid);
	}
}
